package com.wf.it.common.util;

import com.wf.it.common.vo.Result;

import java.lang.reflect.*;
import java.util.*;

public class ForeignHelper2 {


    public static Result fillMap(
            Result pkResult,Object fkProxy,String fkProxyMethod
            ,String pkKeyProperyName,String pkMapProperyName,String resultMapKey){
        try {
            Method[] methods=fkProxy.getClass().getDeclaredMethods();
            Method fkMethod=null;
            for(Method m:methods){
                if(m.getName().equalsIgnoreCase(fkProxyMethod)) {
                    fkMethod = m;
                    break;
                }
            }
            Class argClass=fkMethod.getParameterTypes()[0];
            Object arg=null;
            if(argClass.isArray()) {
                Set set = getKeys(pkResult, pkKeyProperyName);
                arg = Array.newInstance(argClass.getComponentType(), set.size());
                set.toArray((Object[]) arg);
            }else if(argClass.isAssignableFrom(List.class)) {
                Set set = getKeys(pkResult, pkKeyProperyName);
                arg=new ArrayList<>(set);
            }else{
                Object pk=pkResult.getObj();
                Field keyField= pk.getClass().getDeclaredField(pkKeyProperyName);
                keyField.setAccessible(true);
                arg=keyField.get(pk);
            }
            Result fkResult = (Result) fkMethod.invoke(fkProxy, new Object[]{arg});
            fillMap(pkResult,fkResult,pkKeyProperyName,pkMapProperyName,resultMapKey);
            return pkResult;
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }

    public static void fillMap(Result pkResult,Result fkResult
            ,String pkKeyProperyName,String pkMapProperyName,String resultMapKey){
        if(pkResult.getState()!=200)
            return;
        try {
            List pkList=null;
            if(pkResult.getObj() instanceof Collection) {
                pkList = (List) pkResult.getObj();
                fillMap(pkList,fkResult.getObj(),(fkResult.getState()!=200?fkResult.getMsg():null),pkKeyProperyName,pkMapProperyName,resultMapKey);
            }else{
                fillMap(pkResult.getObj(),fkResult.getObj(),(fkResult.getState()!=200?fkResult.getMsg():null),pkKeyProperyName,pkMapProperyName,resultMapKey);
            }
           /* else
               pkList=Collections.singletonList(pkResult.getObj());
            for(Object pk:pkList) {
                //获取doc.getDeptName()
                Field keyField= pk.getClass().getDeclaredField(pkKeyProperyName);
                keyField.setAccessible(true);
                Object fkvalue=keyField.get(pk);
                //doc.getMap();
                Field mapField= pk.getClass().getDeclaredField(pkMapProperyName);
                mapField.setAccessible(true);
                Map<String,Object> pkmap= (Map<String, Object>) mapField.get(pk);

                if(fkResult.getState()==200) {
                    Object fkValue=fkResult.getObj();
                    if(fkValue instanceof Map)
                        pkmap.put(resultMapKey, ((Map)fkValue).get(fkvalue));
                    else
                        pkmap.put(resultMapKey,fkValue);
                }
                else
                    pkmap.put(resultMapKey+"_err",fkResult.getMsg());
            }*/
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }

    public static void fillMap(List pkList,List fkList,String fkIdName,String fkErrMsg
            ,String pkKeyProperyName,String pkMapProperyName,String resultMapKey){
        try {
            //Map fkMap=fkList.stream().collect(Collectors.toMap())
            Map fkMap=new HashMap();
            Field fkIdField=null;
            for(Object fk:fkList) {
                if (fkIdField == null) {
                    fkIdField = fk.getClass().getDeclaredField(fkIdName);
                    fkIdField.setAccessible(true);
                }
                fkMap.put(fkIdField.get(fk), fk);
            }
            fillMap(pkList,fkMap,fkErrMsg,pkKeyProperyName,pkMapProperyName,resultMapKey);
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }

    public static void fillMap(List pkList,Map fkMap,String fkErrMsg
            ,String pkKeyProperyName,String pkMapProperyName,String resultMapKey){
        try {
            Field keyField=null;
            for(Object pk:pkList) {
                if(keyField==null) {
                    keyField = pk.getClass().getDeclaredField(pkKeyProperyName);
                    keyField.setAccessible(true);
                }
                Object fkvalue=keyField.get(pk);
                fillMap(pk,fkMap.get(fkvalue),fkErrMsg,pkKeyProperyName,pkMapProperyName,resultMapKey);
            }
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }


    public static void fillMap(Object pkObj,Object fkObj,String fkErrMsg
            ,String pkKeyProperyName,String pkMapProperyName,String resultMapKey){
        try {

                Field mapField= pkObj.getClass().getDeclaredField(pkMapProperyName);
                mapField.setAccessible(true);
                Map<String,Object> pkmap= (Map<String, Object>) mapField.get(pkObj);
                if(fkObj==null&&!fkErrMsg.isEmpty())
                    pkmap.put(resultMapKey+"_err",fkErrMsg);
                else
                    pkmap.put(resultMapKey, fkObj);

        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }



    public  static <T> Set<T> getKeys(Result srcRes,String keyProperyName){
        return ForeignHelper2.<T>getKeys((List)srcRes.getObj(),keyProperyName);
    }
    public  static <T> Set<T> getKeys(List srcList,String keyProperyName){
        try {
            Set<T> set = new HashSet();
            Class c = null;
            for (Object o : srcList) {
                if (c == null)
                    c = o.getClass();
                Field keyField = c.getDeclaredField(keyProperyName);
                keyField.setAccessible(true);
                T value= (T) keyField.get(o);
                set.add(value);
            }
            return set;
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }
    public  static <T> List<T> getKey2(List srcList,String keyProperyName){
        Set<T> set=getKeys(srcList,keyProperyName);
        return new ArrayList<T>(set);
    }



    //-------------------------------------------------------------------------
    public  static String[] getStringKeys(Result srcRes,String keyProperyName){
        Set<String> keys= ForeignHelper2.<String>getKeys(srcRes,keyProperyName);
        return keys.toArray(new String[keys.size()]);
    }

    public  static Integer[] getIntKeys(Result srcRes,String keyProperyName){
        Set<Integer> keys= ForeignHelper2.<Integer>getKeys(srcRes,keyProperyName);
        return keys.toArray(new Integer[keys.size()]);
    }

    public  static Long[] getLongKeys(Result srcRes,String keyProperyName){
        Set<Long> keys= ForeignHelper2.<Long>getKeys(srcRes,keyProperyName);
        return keys.toArray(new Long[keys.size()]);
    }
    //----------------------------------------------------------------------------
    public  static String[] getStringKeys(List srcList,String keyProperyName){
        Set<String> keys= ForeignHelper2.<String>getKeys(srcList,keyProperyName);
        return keys.toArray(new String[keys.size()]);
    }

    public  static Integer[] getIntKeys(List srcList,String keyProperyName){
        Set<Integer> keys= ForeignHelper2.<Integer>getKeys(srcList,keyProperyName);
        return keys.toArray(new Integer[keys.size()]);
    }

    public  static Long[] getLongKeys(List srcList,String keyProperyName){
        Set<Long> keys= ForeignHelper2.<Long>getKeys(srcList,keyProperyName);
        return keys.toArray(new Long[keys.size()]);
    }


}
